package com.waleipt.api.es.tcptransport;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
import org.elasticsearch.node.Node;
import org.elasticsearch.tasks.TaskManager;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.RequestHandlerRegistry;
import org.elasticsearch.transport.TransportRequest;
import org.elasticsearch.transport.TransportRequestHandler;
import org.elasticsearch.transport.TransportRequestOptions;
import org.elasticsearch.transport.TransportResponse;
import org.elasticsearch.transport.TransportResponseHandler;
import org.elasticsearch.transport.TransportResponseOptions;
import org.elasticsearch.transport.TransportServiceAdapter;
import org.elasticsearch.transport.TransportSettings;
import org.elasticsearch.transport.netty4.Netty4Transport;

public class Server_Node
{
	ServerTransportServiceAdapter adapter = new ServerTransportServiceAdapter() ;
	Netty4Transport _server ;
	public Server_Node( int port )
	{
		ThreadPool threadPool = new ThreadPool(Settings.builder()
				.put(Node.NODE_NAME_SETTING.getKey(), this.getClass().getName() )
				.build()) ;
		Settings server_settings = Settings.builder()
//			.put(TcpTransport.PING_SCHEDULE.getKey(), "1000ms" )
				.put(TransportSettings.BIND_HOST.getKey(), "10.100.33.155" )
				.put(TransportSettings.PUBLISH_HOST.getKey(), "10.100.33.155" )
				.put(TransportSettings.PORT.getKey(), port )
				.build() ;
		
		_server = new Netty4Transport(server_settings, 
				threadPool, 
				new NetworkService(server_settings, Collections.emptyList()), 
				new BigArrays(Settings.EMPTY, null), 
				new NamedWriteableRegistry(Collections.emptyList()), 
				new NoneCircuitBreakerService()) ;
		
		// 此TransportServiceAdapter会对不同业务协议进行接受处理
		_server.transportServiceAdapter( adapter );
	}
	
	public <Request extends TransportRequest> void regHandleRequest( String action, Supplier<Request> requestFactory, TransportRequestHandler<Request> requsetHandler )
	{
		adapter.regHadlerRequest(action, requestFactory, requsetHandler) ;
	}
	
	public void start()
	{
		_server.start();
	}
	
	
	
	class ServerTransportServiceAdapter implements TransportServiceAdapter
	{
		volatile Map<String, RequestHandlerRegistry> requestHandlers = new HashMap<>() ;
		
		public ServerTransportServiceAdapter() {
		}
		
		public <Request extends TransportRequest> RequestHandlerRegistry regHadlerRequest( String action, Supplier<Request> requestFactory, TransportRequestHandler<Request> requsetHandler )
		{
			TaskManager taskManager = new TaskManager( Settings.builder().build() ) ;
			String executor = ThreadPool.Names.SAME ;
			boolean forceExecution = false ;
			boolean canTripCircuitBreaker = false ;
			RequestHandlerRegistry<Request> reg = new RequestHandlerRegistry<Request>( action, requestFactory, taskManager, 
					requsetHandler, 
					executor, forceExecution, canTripCircuitBreaker) ;
			return requestHandlers.put( action, reg) ;
		}
		
		@Override
		public void addBytesReceived(long size) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void addBytesSent(long size) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onRequestSent(DiscoveryNode node, long requestId, String action, TransportRequest request,
				TransportRequestOptions options) {
			// TODO Auto-generated method stub
			
		}
		
		@Override
		public void onResponseSent(long requestId, String action, TransportResponse response,
				TransportResponseOptions options) {
		}
		
		@Override
		public void onResponseSent(long requestId, String action, Exception e) {
			// TODO Auto-generated method stub
			
		}
		
		// 接受响应处理客户端处理
		@Override
		public TransportResponseHandler onResponseReceived(long requestId) {
			return null ;
		}
		
		@Override
		public void onRequestReceived(long requestId, String action) {
			// TODO Auto-generated method stub
			
		}
		
		// 接受请求处理服务端处理
		@Override
		public RequestHandlerRegistry getRequestHandler(String action) {
			return requestHandlers.get(action);
		}
		
	}
}

